﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Threading;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32;

namespace ProxyServerEmulator
{
    public partial class frmMain : Form
    {
        #region Read Proxy Options of Windows
        [DllImport("wininet.dll")]
        public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);
        public const int INTERNET_OPTION_SETTINGS_CHANGED = 39;
        public const int INTERNET_OPTION_REFRESH = 37;
        static bool settingsReturn, refreshReturn;
        #endregion

        Server HTTPServer;
        /// <summary>
        /// Constructor Function
        /// </summary>
        public frmMain()
        {
            InitializeComponent();
            List<IPAddress> IP = new List<IPAddress>();
            IP = ListLocalIP();
            foreach (var item in IP)
            {
                cmbIP.Items.Add(item.ToString());
            }
            cmbIP.SelectedIndex = 0;
            chkUseProxy.Enabled = false;

            // Get the proxy setting from Internet Options
            RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", false);
            try
            {
                int Enable = Convert.ToInt32(registry.GetValue("ProxyEnable"));
                string Server = registry.GetValue("ProxyServer").ToString();
                if (Enable == 1 && Server != null)
                    chkUseProxy.Checked = true;
                else chkUseProxy.Checked = false;
            }
            catch (NullReferenceException ex)
            {
                chkUseProxy.Checked = false;
            }
        }

        /// <summary>
        /// Start or Stop Proxy Server
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonItem1_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(cmbIP.Text) || String.IsNullOrEmpty(txtPort.Text))
            {
                MessageBox.Show("Please Input All Need Data. Host IP or Port Is Missing!");
                return;
            }
            if (Int32.Parse(txtPort.Text) < 1024 || Int32.Parse(txtPort.Text) > 49151)
            {
                MessageBox.Show("Port Muste Be Greater Than 1023 and Less Than 49152");
                return;
            }
            HTTPServer = new Server(IPAddress.Parse(cmbIP.Text), Int32.Parse(txtPort.Text));
            if (btnStart.Text == "Start Server")
            {
                btnStart.Text = "Stop Server";
                HTTPServer.Start();
                chkUseProxy.Enabled = true;
                lblStatus.Text = "Proxy Server Started At: " + cmbIP.Text + ":" + txtPort.Text;
                cmbIP.Enabled = false;
                txtPort.Enabled = false;
            }
            else
            {
                btnStart.Text = "Start Server";
                HTTPServer.Stop();
                chkUseProxy.Enabled = false;
                lblStatus.Text = "Proxy Server Stopped!";
                cmbIP.Enabled = true;
                txtPort.Enabled = true;
            }
        }

        /// <summary>
        /// Get the list local IP
        /// </summary>
        /// <returns></returns>
        public static List<IPAddress> ListLocalIP()
        {
            List<IPAddress> IP = new List<IPAddress>();
            try
            {
                IPHostEntry he = Dns.Resolve(Dns.GetHostName());
                for (int i = 0; i < he.AddressList.Length; i++)
                {
                    IP.Add(he.AddressList[i]);
                }
                return IP;
            }
            catch
            {
                IP.Add(IPAddress.Any);
                return IP;
            }
        }
        private void txtAddress_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                e.Handled = true;
                Thread browse = new Thread(new ThreadStart(GoToAddress));
                browse.IsBackground = true;
                browse.Start();
            }
        }

        private void GoToAddress()
        {
            webBrowser.Stop();
            string URI = txtAddress.Text;
            if (Uri.IsWellFormedUriString(URI,UriKind.RelativeOrAbsolute))
            {
                webBrowser.Navigate(URI);
            }

        }

        private void GoToAddress(string URI)
        {
            webBrowser.Stop();
            if (Uri.IsWellFormedUriString(URI, UriKind.RelativeOrAbsolute))
            {
                webBrowser.Navigate(URI);
            }

        }

        private void btnReturn_Click(object sender, EventArgs e)
        {
            try
            {
                Thread browse = new Thread(new ThreadStart(GoToAddress));
                browse.IsBackground = true;
                browse.Start();
            }
            catch
            { }
            
        }
        private void btnHome_Click(object sender, EventArgs e)
        {
            GoToAddress("http://google.com.vn");
        }

        private void btnBack_Click(object sender, EventArgs e)
        {
            if (webBrowser.CanGoBack)
                webBrowser.GoBack();
        }

        private void btnNext_Click(object sender, EventArgs e)
        {
            if (webBrowser.CanGoForward)
                webBrowser.GoForward();
        }

        private void webBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
        {
            txtAddress.Text = webBrowser.Url.ToString();
            this.Text = "Proxy Server Emulator - " + webBrowser.DocumentTitle.ToString();
        }

        private void chkUseProxy_Click(object sender, EventArgs e)
        {
            RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
            if (chkUseProxy.Checked == true)
            {                
                registry.SetValue("ProxyEnable", 1);
                registry.SetValue("ProxyServer", cmbIP.Text + ":" + txtPort.Text);
            }
            else
            {
                registry.SetValue("ProxyEnable", 0);
                registry.SetValue("ProxyServer", "");
            }
            settingsReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);
            refreshReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);
        }

        private void btnBanned_Click(object sender, EventArgs e)
        {
            frmBannedList Banned = new frmBannedList();
            Banned.ShowDialog();
        }

        private void webBrowser_ProgressChanged(object sender, WebBrowserProgressChangedEventArgs e)
        {
            lblStatus.Text = webBrowser.StatusText;
        }

        private void txtPort_KeyPress(object sender, KeyPressEventArgs e)
        {
            if ((e.KeyChar < '0') || (e.KeyChar > '9')) e.Handled = true;
        }

        private void txtPort_TextChanged(object sender, EventArgs e)
        {
            txtPort.KeyPress += new KeyPressEventHandler(txtPort_KeyPress);
        }
    }
}